package charts.series.bars; 

import charts.series.Element;
import flash.display.Sprite;
import flash.geom.Point;
import hxjson2.JSON;
import string.Utils;
import elements.axis.XAxisLabels;

class StackCollection extends Element {

	var tip_pos:flash.geom.Point;
	var vals:Array<Dynamic>;
	public var colours:Array<String>;
	var group:Float;
	var total:Float;
	
	public function new( index:Float, style:Dynamic, group:Float ) {
		
		this.tooltip = style.tip;
		// this is very similar to a normal
		// PointBarBase but without the mouse
		// over and mouse out events
		this.index = index;
		
		var item:Dynamic;
		
		// a stacked bar has n Y values
		// so this is an array of objects
		this.vals = cast( style.values, Array);
		
		this.total = 0;
		for ( item in this.vals ) {
			if( item != null ) {
				if( Std.is( item, Number) )
					this.total += item;
				else
					this.total += item.val;
			}
		}
	
		//
		// parse our HEX colour strings
		//
		this.colours = new Array();
		for (colour in style.colours )
			this.colours.push( string.Utils.get_colour( colour ) );
			
		this.group = group;
		this.visible = true;
		
		var prop:String;
		
		var n:Float;	// <-- ugh, leaky variables.
		var bottom:Int = 0;
		var top:Int = 0;
		var colr:Float;
		var count:Int = 0;

		for ( item in this.vals )
		{
			// is this a null stacked bar group?
			if( item != null )
			{
				colr = this.colours[(count % this.colours.length)]
				
				var value:Dynamic = {
					top:		0,		// <-- set this later
					bottom:		bottom,
					colour:		colr,		// <-- default colour (may be overriden later)
					total:		this.total,
					tip:		this.tooltip,
					alpha:		style.alpha
				}
			
				//
				// a valid item is one of [ Number, Object, null ]
				//
				if( Std.is( item, Number) ) {
					top += item;
				}
				else
				{
					// MERGE:
					top += item.val;
					if( item.colour )
						value.colour = string.Utils.get_colour(item.colour);
						
					if( item.tip )
						value.tip = item.tip;
				}
				
				value.top = top;
				
				var p:Stack = new Stack( index, value, group );
				this.addChild( p );
				
				bottom = top;
				count++;
			}
		}
	}
	

	public override function resize( sc:ScreenCoordsBase ):Void {
		
		for ( i in 0...this.numChildren)
		{
			var e:Element = cast( this.getChildAt(i), Element);
			e.resize( sc );
		}
	}
	
	//
	// for tooltip closest - return the middle point
	// of this stack
	//
	public override function get_mid_point():flash.geom.Point {
		
		// get the first bar in the stack
		var e:Element = cast( this.getChildAt(0), Element);
			
		return e.get_mid_point();
	}
	
	//
	// called by get_all_at_this_x_pos
	//
	public function get_children(): Array<Dynamic> {
		
		var tmp:Array<Dynamic> = [];
		for ( i in 0...this.numChildren) {
			tmp.push( this.getChildAt(i) );
		}
		return tmp;
	}
	
	public override function get_tip_pos():Dynamic {
		//
		// get top item in stack
		//
		var e:Element = cast( this.getChildAt(this.numChildren-1), Element);
		return e.get_tip_pos();
	}
	
	
	public override function get_tooltip():String {
		//
		// is the mouse over one of the bars in this stack?
		//
		
		// trace( this.numChildren );
		for ( i in 0...this.numChildren)
		{
			var e:Element = cast( this.getChildAt(i), Element);
			if ( e.is_tip )
			{
				//trace( 'TIP' );
				return e.get_tooltip();
			}
		}
		//
		// the mouse is *near* our stack, so show the 'total' tooltip
		//
		return this.tooltip;
	}
	
	/**
		* See Element
		*/
	public override function tooltip_replace_labels( labels:XAxisLabels ):Void {
		
		for ( i in 0...this.numChildren) {
			var e:Stack = cast( this.getChildAt(i), Stack);
			e.replace_x_axis_label( labels.get( this.index ) );
		}
	}
}
